home *** CD-ROM | disk | FTP | other *** search
/ Pascal Super Library / Pascal Super Library (CW International)(1997).bin / PGM_TOOL / TCUNIT / TCUNIT.PAS < prev    next >
Pascal/Delphi Source File  |  1989-07-02  |  6KB  |  214 lines

  1. (*
  2.  *    PROGRAM : TCUnit--typed-constant editor
  3.  *    SYSTEM  : Turbo Pascal 4.0, 5.0, and 5.5
  4.  *    AUTHOR  : (C) 1988, 1989 by Tom Swan
  5.  *)
  6.  
  7. UNIT TCUnit;
  8.  
  9.  
  10. INTERFACE
  11.  
  12.  
  13. PROCEDURE GetWord( prompt : String; VAR v : Word; 
  14.    low, high : Word );
  15.  
  16. PROCEDURE GetStr( prompt : String; VAR s : String; 
  17.    maxLen : Word );
  18.  
  19. FUNCTION ChangesSaved( fileName, searchStr : String;
  20.    cbase, ebase : Word ) : Boolean;
  21.  
  22.  
  23. IMPLEMENTATION
  24.  
  25. USES  Crt;     { Standard Borland display unit }
  26.  
  27. TYPE  ExeFile = File OF Char;    { Reads EXE files as file of char }
  28.  
  29.  
  30. PROCEDURE GetWord( prompt : String; VAR v : Word; low, high : Word );
  31.  
  32. { Prompt for word value, displaying prompt string and limiting
  33. response in v to the range low..high. }
  34.  
  35. VAR   response : String[8];      { Holds response to prompt }
  36.       newValue : Word;           { Possible new value for v }
  37.       e : Integer;               { Error code for Val() }
  38.  
  39. BEGIN
  40.    ClrScr;
  41.    Writeln;
  42.    Writeln( prompt, ' = ', v );
  43.    Writeln;
  44.    Writeln( 'Enter new value from ', low, ' to ', high );
  45.    Write(   'or press Enter for no change: ' );
  46.    Readln( response );
  47.    IF Length( response ) > 0 THEN
  48.    BEGIN
  49.       Val( response, newValue, e );
  50.       IF ( e = 0 ) AND ( low <= newValue ) AND ( newValue <= high ) 
  51.        THEN 
  52.          v := newValue
  53.        ELSE
  54.          BEGIN
  55.             Writeln;
  56.             Write( 'Entry error.  Press Enter...' );
  57.             Readln
  58.          END { else }
  59.    END { if }
  60. END; { GetWord }
  61.  
  62.  
  63. PROCEDURE GetStr( prompt : String; VAR s : String; maxLen : Word );
  64.  
  65. { Prompt for string, displaying prompt string and limiting response
  66. in s to string length 0..maxLen. }
  67.  
  68. VAR   response : String;      { Holds response to prompt }
  69.  
  70. BEGIN
  71.    ClrScr;
  72.    Writeln;
  73.    Writeln( prompt, ' = ', s );
  74.    Writeln;
  75.    Writeln( 'Enter new string with up to ', maxLen, ' characters' );
  76.    Write(   'or press Enter for no change: ' );
  77.    Readln( response );
  78.    IF Length( response ) > 0 THEN
  79.    BEGIN
  80.       IF Length( response ) <= maxLen
  81.        THEN 
  82.          s := response
  83.        ELSE
  84.          BEGIN
  85.             Writeln;
  86.             Write( 'Entry error.  Press Enter...' );
  87.             Readln
  88.          END { else }
  89.    END { if }
  90. END; { GetStr }
  91.  
  92.  
  93. PROCEDURE ShowError( e : Integer );
  94.  
  95. { Display an error message.  e>0 = I/O error; e<0 = other error }
  96.  
  97. BEGIN
  98.    IF e > 0
  99.       THEN Writeln( 'I/O Error #', e )
  100.       ELSE Writeln( 'Error in EXE file format' );
  101.    Writeln;
  102.    Writeln( 'WARNING: EXE file may be damaged!' );
  103.    Writeln;
  104.    Write( 'Press Enter...' );
  105.    Readln
  106. END; { ShowError }
  107.  
  108.  
  109. {$i-}    { Shut off I/O error checks }
  110.  
  111.  
  112. FUNCTION FoundCBase( VAR f : ExeFile; VAR searchStr : String;
  113.    VAR offset : LongInt ) : Boolean;
  114.  
  115. { Return True if searchString (CBase) is found in file f.  If found,
  116. then return byte offset to string in file. }
  117.  
  118. VAR   position : LongInt;        { Possible position of match }
  119.       ch : Char;                 { Holds candidate bytes from file }
  120.  
  121.    FUNCTION FoundMatch : Boolean;
  122.    { True if current position = search string }
  123.    VAR   i : Integer;   { searchStr index }
  124.    BEGIN
  125.       FOR i := 2 TO Length( searchStr ) DO
  126.       BEGIN
  127.          Read( f, ch );
  128.          IF ch <> searchStr[i] THEN
  129.          BEGIN
  130.             FoundMatch := False;
  131.             Exit
  132.          END { if }
  133.       END; { for }
  134.       FoundMatch := True
  135.    END; { FoundMatch }
  136.  
  137. BEGIN
  138.    Reset( f );             { Start search at beginning of file }
  139.    WHILE NOT Eof( f ) DO
  140.    BEGIN
  141.       Read( f, ch );
  142.       IF ch = searchStr[1] THEN        { Test one char }
  143.       BEGIN
  144.          position := FilePos( f );     { Remember position }
  145.          IF FoundMatch THEN            { Check for match }
  146.          BEGIN
  147.             offset := position - 2;    { Found: return offset }
  148.             (* Writeln; Writeln( 'Offset = ', offset ); *)
  149.             FoundCBase := True;        { Set function result }
  150.             Exit                       { Stop searching }
  151.          END ELSE 
  152.             Seek( f, position )        { Continue search }
  153.       END { if }
  154.    END; { while }
  155.    FoundCBase := False     { searchStr isn't there }
  156. END; { FoundCBase }
  157.  
  158.  
  159. PROCEDURE SaveData( VAR f : ExeFile; offset, cbase, len : LongInt;
  160.   VAR e : Integer );
  161.  
  162. { Write len bytes to file f, beginning at byte #offset in the file
  163. and transferring from memory len bytes starting at DS:cbase.  Return
  164. any errors in e.  This copies the in-memory typed constants to the
  165. EXE file image on disk. }
  166.  
  167. VAR   i : Word;      { Mem[] array index }
  168.  
  169. BEGIN
  170.    Seek( f, offset );
  171.    FOR i := 0 TO ( len - 1 ) DO
  172.    BEGIN
  173.       Write( f, Char( Mem[ DSeg:( cbase + i ) ] ) );
  174.       e := IoResult;
  175.       IF e <> 0 THEN Exit
  176.    END { for }
  177. END; { SaveData }
  178.  
  179.  
  180. FUNCTION ChangesSaved( fileName, searchStr : String; cbase, 
  181.    ebase : Word ) : Boolean;
  182.  
  183. { Return True if typed constants in memory are written to disk.
  184. fileName must be a Turbo Pascal compiled EXE file.  searchStr
  185. should equal the CBase marker string at the start of the typed
  186. constants area.  cbase should be the in-memory offset to the CBase
  187. typed constant.  ebase should be the in-memory offset to the EBase
  188. typed constant. }
  189.  
  190. VAR   f : ExeFile;         { Read .EXE as a char file }
  191.       offset : LongInt;    { Byte offset to CBase in .EXE file }
  192.       err : Integer;       { Error code }
  193.  
  194. BEGIN
  195.    GotoXY( 1, 25 );
  196.    ClrEol;
  197.    Write( 'Saving changes to ', fileName, '. Please wait...' );
  198.    Assign( f, fileName );
  199.    Reset( f );
  200.    err := IoResult;
  201.    IF err = 0 THEN
  202.       IF FoundCBase( f, searchStr, offset )
  203.          THEN SaveData( f, offset, cbase, ( ebase - cbase ), err );
  204.    ChangesSaved := ( err = 0 );  { i.e. True if no error }
  205.    Writeln;
  206.    IF err = 0
  207.       THEN Writeln( 'Changes saved' )
  208.       ELSE ShowError( err );
  209.    Close( f )
  210. END; { ChangesSaved }
  211.  
  212.  
  213. END. { TCUnit }
  214.